home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Graphic Elements 3 / GEDemo / Cannon.c next >
Text File  |  1995-08-25  |  6KB  |  225 lines

  1. /*
  2.     Cannon.c
  3.     
  4.     Cannon scene for GEDemo
  5.     
  6.     Copyright 1993 by Al Evans. All rights reserved.
  7.     
  8.     11/3/93
  9.     
  10. */
  11.  
  12. #include "Cannon.h"
  13. #include "Rects.h"
  14. #include "Motion.h"
  15. #include "SFXCtrlr.h"
  16. #include "SFXProcs.h"
  17. #include "GESound.h"
  18.  
  19.  
  20. //static MotionParams    ballMotion;
  21.  
  22. pascal void DisposeBall(GEWorldPtr world, GrafElPtr element)
  23. {
  24.     if (element->drawData)
  25.         DisposPtr(element->drawData);
  26.     if (element->changeData)
  27.         DisposPtr(element->changeData);
  28. }
  29.  
  30.  
  31. Boolean LoadCannonScene(GEWorldPtr world)
  32. {
  33.     GrafElPtr        cannon, thisElement;
  34.     short            smokeWidth, smokeHeight;
  35.     MotionParams     *ballMotion;
  36.  
  37.     //Get cannon picture
  38.     cannon = NewBasicPICT(world, cannonID, cannonPlane, rCannonPic, 
  39.                                     transparent, cannonLeft, cannonTop);
  40.  
  41.     if (cannon == nil) return false;
  42.     
  43.     //Get cannonball picture
  44.     thisElement = NewBasicPICT(world, ballID, ballPlane, rBallPic,
  45.                                     transparent, cannonLeft - 8, cannonTop - 8);
  46.     if (thisElement == nil) return false;
  47.  
  48.     //Draw cannonball masked
  49.     thisElement->drawData = MakeMask(&((GrafPtr) thisElement->graphWorld)->portBits, 0);
  50.     thisElement->copyMode = srcCopy;
  51.     
  52.     //Be sure to Dispose Mask & motion params
  53.     SetCleanupProc(world, ballID, DisposeBall);
  54.  
  55.     
  56.     //Initialize motion parameters
  57.     ballMotion = (MotionParams *) NewPtr(sizeof(MotionParams));
  58.     ballMotion->limitRect = world->animationRect;
  59.     RectOffset(&ballMotion->limitRect, 0, ScaleToWorld(world,-80));
  60.     InitMotion(ballMotion, 2, 90);
  61.     
  62.     //Initialize cannonball's motion
  63.     SetAutoChange(world, ballID, DoCannonBall, (Ptr) ballMotion, 33);
  64.     
  65.     //Initialize cannonball's collision params
  66.     SetCollision(world, ballID, DoBallHit, 650);
  67.     
  68.     //Cannonball is initially invisible
  69.     ShowElement(world, ballID, false);
  70.     
  71.     //Get animated smoke picture
  72.     thisElement = NewAnimatedGraphic(world, smokeID, smokePlane, rSmokePic,
  73.                                     transparent, 0, 0, 3);
  74.     if (thisElement == nil) return false;
  75.     
  76.     //Position smoke in relation to cannon
  77.     smokeWidth = RectWidth(&thisElement->graphRect);
  78.     smokeHeight = RectHeight(&thisElement->graphRect);
  79.     PtrMoveElementTo(world, thisElement, ScaleToWorld(world, cannonLeft + 16) - smokeWidth, 
  80.                                     ScaleToWorld(world, cannonTop + 16) - smokeHeight, false);
  81.     
  82.     //Set smoke animation
  83.     AnimateGraphic(world, smokeID, 170, oneshotvanish);
  84.     
  85.     //Smoke is initially invisible
  86.     ShowElement(world, smokeID, false);
  87.     
  88.     //Smoke is attached to cannon
  89.     cannon->slaveGrafEl = thisElement;
  90.     
  91.     //Get "FIRE" button
  92.     thisElement = NewButtonSensor(world, fBtnID, btnPlane, rFBtnPic, 434, 193);
  93.     if (thisElement == nil) return false;
  94.     SetSensorAction(world, fBtnID, ShootCannon);
  95.     
  96.     return true;
  97. }
  98.  
  99. pascal void DoCannonBall(GEWorldPtr world, GrafElPtr ball)
  100. {
  101.     MParamPtr    motion;
  102.     
  103.     motion = (MParamPtr) ball->changeData;
  104.     
  105.     if ((motion->currMotion.v == 0) && (motion->currMotion.h == 0)) {
  106.         (void) DoGESFX(world, 'SFXB', ball, SFXVWipe,
  107.                         RectHeight(&ball->animationRect), 0, 200, false, true);
  108.         return;
  109.     }
  110.     MoveElement(world, ball->objectID, motion->currMotion.h, motion->currMotion.v);
  111.     switch (CheckLimits(&ball->animationRect, &motion->limitRect)) {
  112.     case down:
  113.         if (motion->currMotion.v > 0) {
  114.             if (world->userData != nil)
  115.                 GEScheduleSound((GESoundPtr) world->userData, rBallSnd, 1, 0);
  116.             DoBounce(v, motion);
  117.         }
  118.         DoFriction(motion);
  119.         break;
  120.     case right:
  121.         if (motion->currMotion.h > 0) {
  122.             if (world->userData != nil)
  123.                 GEScheduleSound((GESoundPtr) world->userData, rBallSnd, 1, 0);
  124.             DoBounce(h, motion);
  125.         }
  126.         break;
  127.     case left:
  128.         if (motion->currMotion.h < 0) {
  129.             if (world->userData != nil)
  130.                 GEScheduleSound((GESoundPtr) world->userData, rBallSnd, 1, 0);
  131.             DoBounce(h, motion);
  132.         }
  133.         break;
  134.     default:
  135.         motion->currMotion.v++;
  136.         break;
  137.     }
  138. }
  139.  
  140. pascal void DoBallHit(GEWorldPtr world, GrafElPtr ball, 
  141.                     GEDirection dir, CollisionPhase phase, GrafElPtr objHit)
  142. {
  143.  
  144.     MParamPtr    motion;
  145.     
  146.     if (phase == collisionBegin) {
  147.         motion = (MParamPtr) ball->changeData;
  148.         switch (dir) {
  149.             case left:
  150.                 if (motion->currMotion.h < 0)
  151.                     DoBounce(h, motion);
  152.                 break;
  153.             case right:
  154.                 if (motion->currMotion.h > 0)
  155.                     DoBounce(h, motion);
  156.                 break;
  157.             case up:
  158.                 if (motion->currMotion.v < 0)
  159.                     DoBounce(v, motion);
  160.                 break;
  161.             case down:
  162.                 if (motion->currMotion.v > 0)
  163.                     DoBounce(v, motion);
  164.                 break;
  165.             case upLeft:
  166.                 if (motion->currMotion.v < 0)
  167.                     DoBounce(v, motion);
  168.                 if (motion->currMotion.h < 0)
  169.                     DoBounce(h, motion);
  170.                 break;
  171.             case downLeft:
  172.                 if (motion->currMotion.v > 0)
  173.                     DoBounce(v, motion);
  174.                 if (motion->currMotion.h < 0)
  175.                     DoBounce(h, motion);
  176.                 break;
  177.             case upRight:
  178.                 if (motion->currMotion.v < 0)
  179.                     DoBounce(v, motion);
  180.                 if (motion->currMotion.h > 0)
  181.                     DoBounce(h, motion);
  182.                 break;
  183.             case downRight:
  184.                 if (motion->currMotion.v > 0)
  185.                     DoBounce(v, motion);
  186.                 if (motion->currMotion.h > 0)
  187.                     DoBounce(h, motion);
  188.                 break;
  189.             
  190.         }
  191.         if (FindElementByID(world, 'SFXP') == nil)    //One at a time, please
  192.         {
  193.             if (world->userData != nil)
  194.                 GEScheduleSound((GESoundPtr) world->userData, rHitSnd, 1, 0);
  195.                 
  196.             (void) DoGESFX(world, 'SFXP', objHit, SFXBlink, 10, 0, 50, true, true);
  197.         }
  198.     }
  199. }
  200.  
  201. pascal void ShootCannon(GEWorldPtr world, GrafElPtr ignore, short fireIt)
  202. {
  203.     GrafElPtr    cannon, ball;
  204.     MParamPtr    ballMotion;
  205. #pragma unused (fireIt)
  206.  
  207.     cannon = FindElementByID(world, cannonID);
  208.     if (cannon) {
  209.         ball = FindElementByID(world, ballID);
  210.         if (ball) {
  211.             ballMotion = (MParamPtr) ball->changeData;
  212.             ballMotion->currMotion.h = -20;
  213.             ballMotion->currMotion.v = -20;
  214.             ballMotion->frictAcc = 0;
  215.             PtrMoveElementTo(world, ball, cannon->animationRect.left - ScaleToWorld(world, 8), 
  216.                     cannon->animationRect.top - ScaleToWorld(world, 8), false);
  217.             ShowElement(world, ballID, true);
  218.         }
  219.         if (world->userData != nil)
  220.             GEScheduleSound((GESoundPtr) world->userData, rFireSnd, 1, 0);
  221.         ShowElement(world, smokeID, true);
  222.     }
  223. }
  224.  
  225.